home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
gui
/
gtlayout.lha
/
Source
/
LTP_TabClass.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-09
|
16KB
|
766 lines
/*
** GadTools layout toolkit
**
** Copyright © 1993-1998 by Olaf `Olsen' Barthel
** Freely distributable.
**
** :ts=4
*/
#ifndef _GTLAYOUT_GLOBAL_H
#include "gtlayout_global.h"
#endif
/*****************************************************************************/
#include <intuition/classes.h>
#include <exec/memory.h>
#include <hardware/blit.h>
#include <clib/alib_protos.h> /* For Coerce/Do/DoSuperMethod */
#include <stdarg.h>
/*****************************************************************************/
#include "Assert.h"
#ifdef DO_TAB_KIND /* Support code */
#define TIA_Labels (TAG_USER+0x90000)
#define TIA_Font (TAG_USER+0x90001)
#define TIA_Screen (TAG_USER+0x90002)
#define TIA_Index (TAG_USER+0x90003)
#define TIA_DrawInfo (TAG_USER+0x90004)
#define TIA_SizeType (TAG_USER+0x90005)
STATIC VOID
DrawCap(struct RastPort *RPort,LONG Left,LONG Top,LONG Width,LONG Height,BOOL Flip)
{
LONG x,y,da,MidX,MidY,r,Full,Push,Mult;
Full = Height;
Height = Width;
MidX = Left;
MidY = Top + Height - 1;
r = Height - 1;
x = 0;
y = r;
da = r - 1;
if(Flip)
{
Push = Width - 1;
Mult = -1;
}
else
{
Push = 0;
Mult = 1;
}
do
{
if(da < 0)
{
y--;
da += y * 2;
}
WritePixel(RPort,Left + Push + Mult * (x + MidX - Left),-y + MidY);
WritePixel(RPort,Left + Push + Mult * (y + MidX - Left),-x + MidY);
da -= (1 + x * 2);
x++;
}
while(x <= y);
Left += Width - 1 - Push;
LTP_DrawLine(RPort,Left,Top + Height,Left,Top + Full - 1);
}
STATIC VOID
RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,LONG Pull)
{
LONG Width,Height;
LONG i;
LONG Pen;
Width = Info->TabWidth;
Height = Info->TabHeight;
SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
for(i = 0 ; i < 4 ; i++)
{
if(i & 1)
{
if(Pens[SHINEPEN] == Pens[SHADOWPEN])
Pen = BACKGROUNDPEN;
else
Pen = SHADOWPEN;
}
else
Pen = SHINEPEN;
LTP_SetAPen(&Info->RPort,Pens[Pen]);
LTP_DrawLine(&Info->RPort,0,Height - 1 - i,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
}
for(i = Info->Count - 1 ; i >= 0 ; i--)
{
if(i != Info->Current)
BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
}
BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
WaitBlit();
BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
}
STATIC VOID
SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
struct TagItem *Tag;
BOOL NeedRefresh = FALSE;
BOOL Disabled;
Disabled = (BOOL)((gadget->Flags & GFLG_DISABLED) != 0);
if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
{
if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
NeedRefresh = TRUE;
}
if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
{
LONG Index = Tag->ti_Data;
if(Index >= Info->Count)
Index = Info->Count - 1;
if(Index != Info->Current)
{
Info->Initial = Info->Current = Index;
NeedRefresh = TRUE;
}
}
if(NeedRefresh)
{
struct RastPort *RPort;
if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
{
DoMethod((Object *)gadget,GM_RENDER,SetInfo->ops_GInfo,RPort,GREDRAW_REDRAW);
ReleaseGIRPort(RPort);
}
}
}
STATIC ULONG
RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,RenderInfo->gpr_Redraw == GREDRAW_UPDATE ? 2 : 0);
return(TRUE);
}
STATIC VOID
DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
{
TabInfo *Info = INST_DATA(class,gadget);
if(Info->Mask || Info->Tabs || Info->BitMap)
WaitBlit();
if(Info->Mask)
{
FreeRaster(Info->Mask,Info->TabWidth,Info->TabHeight);
}
if(Info->Tabs)
{
LONG i;
for(i = 0 ; i < Info->Count ; i++)
LTP_DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
FreeVec(Info->Tabs);
}
LTP_DeleteBitMap(Info->BitMap,FALSE);
}
STATIC ULONG
NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
{
if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
{
TabInfo *Info = INST_DATA(class,gadget);
struct TagItem *Tag,*TagList = SetInfo->ops_AttrList;
struct TextAttr *FontAttr;
LONG Width,Height;
struct DrawInfo *DrawInfo;
STRPTR *Labels;
struct Screen *Screen;
Width = 0;
Height = 0;
FontAttr = NULL;
DrawInfo = NULL;
Labels = NULL;
Screen = NULL;
memset(Info,0,sizeof(TabInfo));
while(Tag = NextTagItem(&TagList))
{
switch(Tag->ti_Tag)
{
case GA_Width:
Width = Tag->ti_Data;
break;
case GA_Height:
Height = Tag->ti_Data;
break;
case TIA_Labels:
Labels = (STRPTR *)Tag->ti_Data;
break;
case TIA_Font:
FontAttr = (struct TextAttr *)Tag->ti_Data;
break;
case TIA_Screen:
Screen = (struct Screen *)Tag->ti_Data;
break;
case TIA_Index:
Info->Current = Tag->ti_Data;
break;
case TIA_DrawInfo:
DrawInfo = (struct DrawInfo *)Tag->ti_Data;
break;
}
}
if(Labels)
{
while(Labels[Info->Count])
Info->Count++;
}
if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
{
struct TextFont *Font;
if(Font = OpenFont(FontAttr))
{
struct RastPort *RPort = &Info->RPort;
InitRastPort(RPort);
SetFont(RPort,Font);
if(Height >= RPort->TxHeight + 11)
{
LONG i,Len,MaxWidth,Remain;
LONG Lean;
if(Info->Current < 0)
Info->Current = 0;
else
{
if(Info->Current >= Info->Count)
Info->Current = Info->Count - 1;
}
Lean = (TextLength(RPort,"O",1) + 1) / 2;
Info->Thick = (DrawInfo->dri_Resolution.Y + DrawInfo->dri_Resolution.X - 1) / DrawInfo->dri_Resolution.X;
if(Info->Thick < 1)
Info->Thick = 1;
for(i = MaxWidth = 0 ; i < Info->Count ; i++)
{
if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
MaxWidth = Len;
}
MaxWidth = Info->Thick + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + Info->Thick;
Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
if(Remain >= Info->Count - 1)
{
if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
{
STATIC const BYTE PenNumbers[] =
{
BACKGROUNDPEN,
SHINEPEN,
SHADOWPEN,
TEXTPEN
};
struct BitMap Mask;
LONG Depth;
LONG MaxPen;
UWORD *Pens = DrawInfo->dri_Pens;
BOOL GotIt = TRUE;
memset(&Mask,0,sizeof(Mask));
for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
{
if(Pens[PenNumbers[i]] > MaxPen)
MaxPen = Pens[PenNumbers[i]];
}
Depth = 8; /* For the sake of the compiler initialize this. */
for(i = 1 ; i <= 8 ; i++)
{
if(MaxPen < (1 << i))
{
Depth = i;
break;
}
}
Info->TabWidth = MaxWidth;
Info->TabHeight = 4 + RPort->TxHeight + 5;
InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
Mask.Planes[1] = NULL;
for(i = 0 ; GotIt && i < 2 ; i++)
{
if(!(Mask.Planes[i] = (PLANEPTR)AllocRaster(Info->TabWidth,Info->TabHeight)))
GotIt = FALSE;
}
for(i = 0 ; GotIt && i < Info->Count ; i++)
{
if(!(Info->Tabs[i].BitMap = LTP_CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
GotIt = FALSE;
}
if(GotIt)
{
Depth = LTP_GetDepth(Screen->RastPort.BitMap);
if(!(Info->BitMap = LTP_CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
GotIt = FALSE;
}
if(GotIt)
{
struct TmpRas TmpRas;
LONG j,Len,Offset,P